package controller;

import api.QrcodeApi;
import common.pojo.CommonResult;
import common.spring.redis.RedisUnits;
import common.utils.JsonUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import pojo.WxUserInfo;
import service.WxUserInfoService;
import service.cfg.ResourceApiFrameworkCfg;
import service.cfg.WxCfg;
import utils.StringUtils;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by asus on 2018/10/18.
 */
@Controller
@RequestMapping("/qrcode")
public class QrcodeController extends ManagerBaseController {
    @Autowired
    WxCfg wxCfg;

    @Autowired
    QrcodeApi qrcodeApi;

    @Autowired
    protected ResourceApiFrameworkCfg cfg;

    @Autowired
    WxUserInfoService infoService;

    @Autowired
    RedisUnits redisUnits;

    private final Logger log = LoggerFactory.getLogger(QrcodeController.class);
    /**
     * 生成个人二维码
     *
     * @param request  将要传递的参数带过来//上级分享者Id//或者其他信息
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public CommonResult getQrCode(HttpServletRequest request, HttpServletResponse response) {
        Map map = parseRequestParamMap(request);
        if (map.get("openId") == null) {
            return CommonResult.returnFailsWrapper("请传入openId");
        }
        if (StringUtils.isBlank(map.get("openId").toString())) {
            return CommonResult.returnFailsWrapper("请传入openId");
        }
        if (StringUtils.isBlank(map.get("shopId").toString())) {
            return CommonResult.returnFailsWrapper("请传入shopId");
        }
        String token = qrcodeApi.getAccessToken();
        if (StringUtils.isBlank(token)) {
            return CommonResult.returnFailsWrapper("token获取失败");
        }
        String openId = map.get("openId").toString();
        WxUserInfo wxUserInfo = infoService.getWxUserInfo(openId);
        map.put("parentId", wxUserInfo.getId());
        CommonResult url = qrcodeApi.returnCode(map, token, openId);
        return url;
    }

    /**
     * 生成代理商二维码
     *
     * @param request  将要传递的参数带过来//上级分享者Id//或者其他信息
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/agentCode", method = RequestMethod.GET)
    public CommonResult getQrCodeAgentId(HttpServletRequest request, HttpServletResponse response) {
        Map map = parseRequestParamMap(request);
        if (map.get("agentId") == null) {
            return CommonResult.returnFailsWrapper("请传入agentId");
        }
        String token = qrcodeApi.getAccessToken();
        if (StringUtils.isBlank(token)) {
            return CommonResult.returnFailsWrapper("token获取失败");
        }
        String agentId = map.get("agentId").toString();
        CommonResult url = qrcodeApi.returnQrCode(token, NumberUtils.toLong(agentId));
        return url;
    }

    /**
     * 生成代理商二维码
     *
     * @param request  将要传递的参数带过来//上级分享者Id//或者其他信息
     * @param response
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/userCode", method = RequestMethod.GET)
    public CommonResult getQrCodes(HttpServletRequest request, HttpServletResponse response) {
        Map map = parseRequestParamMap(request);
        if (map.get("openId") == null) {
            return CommonResult.returnFailsWrapper("请传入openId");
        }
        String token = qrcodeApi.getAccessToken();
        if (StringUtils.isBlank(token)) {
            return CommonResult.returnFailsWrapper("token获取失败");
        }
        WxUserInfo wxUserInfo = infoService.getWxUserInfo(map.get("openId").toString());
        map.put("parentId", wxUserInfo.getId());
        CommonResult url = qrcodeApi.returnCodeMine(map, token, map.get("openId").toString());
        return url;
    }


    @RequestMapping(value = "/goods/poster", method = RequestMethod.POST)
    @ResponseBody
    public CommonResult getGoodsPoster(
            HttpServletRequest request
    ) {
        String sessionId = request.getHeader("sessionId");
        if (org.apache.commons.lang.StringUtils.isBlank(sessionId)) {
            return new CommonResult(3, "请重新登录");
        }
        Map maps = redisUnits.getMap(sessionId);
        if (maps == null || maps.size() == 0) {
            return new CommonResult(3, "");
        }
        WxUserInfo wxUserInfo = infoService.getWxUserInfo(maps.get("openId").toString());
        if (wxUserInfo == null) {
            return CommonResult.returnFailsWrapper("身份信息失效，请重新登录");
        }
        Map map = parseRequestParamMap(request);
        if (map.containsKey("goodsId") && map.get("goodsId") != null && NumberUtils.toLong(map.get("goodsId").toString()) > 0) {
            String token = qrcodeApi.getAccessToken();
            if (StringUtils.isBlank(token)) {
                return CommonResult.returnFailsWrapper("token获取失败");
            }
            log.warn(JsonUtils.toJson(map));
            if(!map.containsKey("shareUpId") || map.get("shareUpId") == null){
                map.put("shareUpId",0);
            }
            try {
                map.put("shareId", wxUserInfo.getId());
                map.put("headUrl", wxUserInfo.getAvatarUrl());
                log.warn(map.get("shareUpId").toString()+":"+161);
                return qrcodeApi.getGoodsPoster(map, token, wxUserInfo.getNickName());
            } catch (IOException e) {
                return CommonResult.returnFailsWrapper("生成失败");
            }
        } else {
            return CommonResult.returnFailsWrapper("生成失败");
        }
    }

    /**
     * 返回个人二维码
     *
     * @param time
     * @param fileName
     * @param response
     * @return
     */
    @RequestMapping(
            value = {"/image/{fileName:.*}"},
            method = {RequestMethod.GET}
    )
    @ResponseBody
    public CommonResult materialDefaultView(@RequestHeader(value = "If-Modified-Since", required = false) String time, @PathVariable("fileName") String fileName, HttpServletResponse response) {
        String type = "";
        if (org.apache.commons.lang.StringUtils.isNotBlank(fileName)) {
            type = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
        }
        File file = new File(String.format("%s%s", new Object[]{this.cfg.getMaterialFileRootPath() + "/", fileName}));
        try {
            if (org.apache.commons.lang.StringUtils.isNotBlank(time)) {
                long e = file.lastModified();
                if (time.equals(String.valueOf(e))) {
                    response.setHeader("Last-Modified", time);
                    response.setStatus(304);
                    return null;
                }
            }

            this.materialReadAndWriteFile(response, file, (Long) null, "image/" + type, false);
            return null;
        } catch (IOException var12) {
            this.logger.error("Error", var12);
            return this.returnFailsWrapper("获取图片失败", new Object[0]);
        }
    }


    private void materialReadAndWriteFile(HttpServletResponse response, File file, Long offset, String contentType, boolean isDownload) throws IOException {
        RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
        if (offset != null) {
            randomAccessFile.seek(offset.longValue());
        }

        if (isDownload) {
            response.setHeader("Content-disposition", "attachment;filename=" + file.getName());
        }

        response.setContentLength((int) file.length());
        response.setContentType(contentType);
        response.addHeader("Last-Modified", String.valueOf(file.lastModified()));
        ServletOutputStream outputStream = response.getOutputStream();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
        byte[] bt = new byte[this.cfg.getMaterialBufferSize()];

        int line;
        while ((line = randomAccessFile.read(bt)) != -1) {
            bufferedOutputStream.write(bt, 0, line);
        }

        bufferedOutputStream.flush();
        bufferedOutputStream.close();
        randomAccessFile.close();
    }



}
